package com.enfi.api.modules.ext.mq.strategy;

import com.alibaba.fastjson.JSONObject;
import com.enfi.api.modules.db.entity.Workorder;
import com.enfi.api.modules.db.entity.WorkorderHistory;
import com.enfi.api.modules.db.entity.WorkorderUser;
import com.enfi.api.modules.db.service.WorkorderHistoryService;
import com.enfi.api.modules.db.service.WorkorderService;
import com.enfi.api.modules.db.service.WorkorderUserService;
import com.enfi.api.modules.ext.jpush.PushBean;
import com.enfi.api.modules.ext.jpush.PushService;
import com.enfi.api.modules.ext.mq.common.MessageTypeEnum;
import com.enfi.api.modules.ext.mq.common.MqConstants;
import com.enfi.api.modules.ext.mq.common.PushTypeEnum;
import com.enfi.api.modules.ext.mq.common.PushWayEnum;
import com.enfi.api.modules.ext.mq.dto.WorkorderUserDTO;
import com.enfi.api.modules.ext.mq.factory.MessageFactory;
import com.enfi.api.modules.ext.websocket.service.WsService;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 工单策略
 * @author xukk
 * @date 2020/3/10
 */
@Service
@Slf4j
public class WorkorderStrategy implements BaseStrategy , InitializingBean {

    private WsService wsService;
    @Autowired
    private PushService pushService;
    @Autowired
    private WorkorderHistoryService workorderHistoryService;
    @Autowired
    private WorkorderService workorderService;
    @Autowired
    private WorkorderUserService workorderUserService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void handle(JSONObject jsonObject) {
        Integer pushType=jsonObject.getInteger(MqConstants.ST.PUSH_TYPE);
        String pushWay=jsonObject.getString(MqConstants.ST.PUSH_WAY);
        if(pushType==null){
            // 默认走websocket
            pushType= PushTypeEnum.WEBSOCKET.getCode();
            jsonObject.put(MqConstants.ST.PUSH_TYPE,pushType);
        }
        if(StringUtils.isEmpty(pushWay)){
            pushWay= PushWayEnum.PC.name();
            jsonObject.put(MqConstants.ST.PUSH_WAY,pushWay);
        }
        Workorder workorder=saveOrUpdate(jsonObject);
        push(workorder);
        log.warn("此次处理结果结束");

    }

    public Workorder saveOrUpdate(JSONObject jsonObject){
        JSONObject jo=jsonObject.getJSONObject("data");
        Workorder workorder = jo.toJavaObject(Workorder.class);
        Workorder example=new Workorder();
        example.setSourceId(workorder.getSourceId());
        Optional<Workorder> o = workorderService.findOne(Example.of(example));
        if(o.isPresent()){
            log.warn("o is not null 修改");
            WorkorderHistory workorderHistory=jo.toJavaObject(WorkorderHistory.class);
            workorderHistory.setFactory(o.get().getFactory());
            workorderHistory.setOfficeCode(o.get().getOfficeCode());
            workorderHistory.setOfficeName(o.get().getOfficeName());
            workorderHistory.setStatus(o.get().getStatus());
            workorderHistory.setUrl(o.get().getUrl());
            workorderHistory.setUuid(o.get().getUuid());
            workorderHistory.setVersion(o.get().getVersion());
            workorderHistory.setUserWorkNumbers(o.get().getUserWorkNumbers());
            workorderHistoryService.save(workorderHistory);
            o.get().setUrl(workorder.getUrl());
            o.get().setStatus(workorder.getStatus());
            o.get().setUuid(UUID.randomUUID().toString()+String.valueOf(System.currentTimeMillis()));
            o.get().setWorkorderStatus(workorder.getWorkorderStatus());
            o.get().setUserWorkNumbers(workorder.getUserWorkNumbers());

            WorkorderUser workorderUser=new WorkorderUser();
            workorderUser.setSourceId(workorder.getSourceId());
            List<WorkorderUser> workorderUserList=workorderUserService.findAll(Example.of(workorderUser));
            workorderUserService.deleteAll(workorderUserList);
            log.warn("清空workorde user:{}",workorder.getSourceId());
            workorderService.save(o.get());

            workorder.setId(o.get().getId());
            workorder.setUuid(o.get().getUuid());
            workorder.setVersion(o.get().getVersion()+1);

            return workorder;
        }else {
            log.warn("o is null 新增");
            workorder.setUuid(UUID.randomUUID().toString()+String.valueOf(System.currentTimeMillis()));
            workorderService.save(workorder);
            return workorder;
        }
    }

    public void push(Workorder workorder){
        if(org.apache.commons.lang3.StringUtils.isBlank(workorder.getUserWorkNumbers())){
            return;
        }
        List<Integer> list1= Lists.newArrayList(1,2);
        List<String> list = Lists.newArrayList(workorder.getUserWorkNumbers().split(",")).stream().map(String::trim).collect(Collectors.toList());
        NamedParameterJdbcTemplate givenParamJdbcTemp = new NamedParameterJdbcTemplate(jdbcTemplate);
        Map<String, Object> args = Maps.newHashMap();
        args.put("refCode", list);
        String sql = "select ref_code,user_code,user_name from js_sys_user where ref_code in(:refCode)";
        List<String> userCodeList=Lists.newArrayList();
        List<WorkorderUserDTO> data = givenParamJdbcTemp.query(sql, args, (rs, index) -> {
            WorkorderUserDTO emp = new WorkorderUserDTO();
            emp.setRefCode(rs.getString("ref_code"));
            emp.setUserCode(rs.getString("user_code"));
            emp.setUserName(rs.getString("user_name"));
            if(!userCodeList.contains(emp.getUserCode())){
                userCodeList.add(emp.getUserCode());
            }
            return emp;
        });

        data.forEach(v -> {
            WorkorderUser workorderUser = new WorkorderUser();
            workorderUser.setUserId(v.getUserCode());
            workorderUser.setUserName(v.getUserName());
            workorderUser.setUserOrderNumber(v.getRefCode());
            workorderUser.setWorkorderId(workorder.getId());
            workorderUser.setSourceId(workorder.getSourceId());
            workorderUser.setUuid(workorder.getUuid());
            workorderUser.setVersion(workorder.getVersion());
            workorderUserService.save(workorderUser);
        });

        list1.forEach(v->{
            switch (v){
                case 1:
                    JSONObject j1 = new JSONObject();
                    JSONObject data1=new JSONObject();
                    data1.put("title",workorder.getTitle());
                    j1.put(MqConstants.ST.MESSAGE_TYPE,MessageTypeEnum.WARNING.name().toLowerCase());
                    j1.put(MqConstants.ST.RESP_TYPE,1);
                    j1.put(MqConstants.ST.PUSH_WAY,PushWayEnum.PC.name().toLowerCase());
                    j1.put(MqConstants.ST.USER_LIST, Joiner.on(",").join(userCodeList));
                    j1.put(MqConstants.ST.DATA,data1.toString());
                    try {
                        wsService.handleFromMq(j1);
                    } catch (Exception e) {
                        log.warn(e.getMessage());
                    }
                    break;
                case 2:
                    try{
                        PushBean pushBean=new PushBean();
                        pushBean.setAlert(workorder.getTitle());
                        log.warn("推送app消息:{},userCode:{}",pushBean,userCodeList);
                        pushService.pushAll(pushBean,userCodeList);
                    }catch (Exception e){
                        log.warn(e.getMessage());
                    }
                    break;
                case 3:
                    break;
                case 4:
                    break;
                default:
            }
        });

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        MessageFactory.register(MessageTypeEnum.WORKORDER, this);
    }
    @Autowired
    public void setWsService(WsService wsService) {
        this.wsService = wsService;
    }
}
